import os
import json
import uuid
import threading
import time
import mimetypes
import traceback
from datetime import datetime
from flask import Flask, render_template, request, jsonify, send_file
from flask_socketio import SocketIO, emit
import requests
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Font, Alignment
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['REPORT_FOLDER'] = 'reports'

# 创建必要的文件夹
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['REPORT_FOLDER'], exist_ok=True)

socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading')

# API配置
API_BASE_URL = "http://localhost:8000"
EXTRACT_API_URL = f"{API_BASE_URL}/api/v1/extract"

# 存储任务结果
task_results = {}


def check_file_format(file_path):
    """检查文件格式是否与扩展名匹配，自动修复缺失的扩展名"""
    try:
        _, ext = os.path.splitext(file_path)
        ext = ext.lower()
        
        # 读取文件头部字节来判断实际格式
        with open(file_path, 'rb') as f:
            header = f.read(16)
        
        # 如果没有扩展名但检测到PDF格式，自动添加.pdf扩展名
        if not ext and header.startswith(b'%PDF'):
            new_path = file_path + '.pdf'
            os.rename(file_path, new_path)
            return True, {'auto_renamed': True, 'new_path': new_path}
        
        # 验证扩展名与实际格式是否匹配
        if ext == '.pdf' and not header.startswith(b'%PDF'):
            return False, f"文件扩展名为PDF但实际不是PDF格式"
        elif ext in ['.jpg', '.jpeg'] and not header.startswith(b'\xff\xd8\xff'):
            return False, f"文件扩展名为JPEG但实际不是JPEG格式"
        elif ext == '.png' and not header.startswith(b'\x89PNG\r\n\x1a\n'):
            return False, f"文件扩展名为PNG但实际不是PNG格式"
        
        return True, {'extension': ext, 'size': os.path.getsize(file_path)}
    except Exception as e:
        return False, f"文件格式检查失败: {str(e)}"


def extract_fields_from_files(file_paths, max_retries=3):
    """
    调用新的字段提取接口，一次性上传多个文件并获取提取结果
    
    Args:
        file_paths: 文件路径列表
        max_retries: 最大重试次数
    
    Returns:
        API响应的JSON数据
    """
    for attempt in range(max_retries):
        try:
            # 检查并修复所有文件格式
            validated_paths = []
            for file_path in file_paths:
                is_valid, check_result = check_file_format(file_path)
                if not is_valid:
                    raise Exception(f"文件 {file_path} 格式检查失败: {check_result}")
                
                # 如果文件被自动重命名，更新文件路径
                if isinstance(check_result, dict) and check_result.get('auto_renamed'):
                    file_path = check_result['new_path']
                
                validated_paths.append(file_path)
            
            # 准备文件数据（form-data格式）
            files = []
            for file_path in validated_paths:
                files.append(('files', (os.path.basename(file_path), open(file_path, 'rb'), 'application/pdf')))
            
            try:
                # 调用提取接口
                response = requests.post(
                    EXTRACT_API_URL,
                    files=files,
                    timeout=300  # 5分钟超时
                )
                
                response.raise_for_status()
                result = response.json()
                
                # 检查响应状态
                if result.get('success'):
                    return result
                else:
                    error_msg = result.get('message', '未知错误')
                    raise Exception(f"字段提取失败: {error_msg}")
            
            finally:
                # 关闭所有打开的文件
                for _, file_tuple in files:
                    if hasattr(file_tuple[1], 'close'):
                        file_tuple[1].close()
                    
        except requests.exceptions.Timeout:
            if attempt == max_retries - 1:
                raise Exception("API调用超时（300秒），请检查网络连接或稍后重试")
        except requests.exceptions.RequestException as e:
            if attempt == max_retries - 1:
                raise Exception(f"网络请求失败: {str(e)}")
        except json.JSONDecodeError as e:
            if attempt == max_retries - 1:
                raise Exception(f"服务器响应格式错误: {str(e)}")
        except Exception as e:
            if attempt == max_retries - 1:
                raise e
        
        if attempt < max_retries - 1:
            time.sleep(2)
    
    return None


def extract_data_from_response(api_response):
    """
    从新API响应中提取完整数据（一级字段 + 项目数组）
    
    新接口响应格式：
    {
        "success": true,
        "data": {
            "fields_data": {
                "进口日期": {"进口日期": {"text": ""}},
                "项目": {"项目": [...]}
            }
        }
    }
    
    需要将其转换为扁平格式：
    {
        "进口日期": {"text": ""},
        "项目": [...]
    }
    """
    try:
        if not api_response.get('success'):
            return {}
        
        fields_data = api_response.get('data', {}).get('fields_data', {})
        if not fields_data:
            return {}
        
        # 提取内层数据（去掉外层的重复字段名）
        extracted_data = {}
        for field_name, field_value in fields_data.items():
            if isinstance(field_value, dict):
                # 提取内层数据
                inner_data = field_value.get(field_name, {})
                extracted_data[field_name] = inner_data
            else:
                extracted_data[field_name] = field_value
        
        return extracted_data
    except Exception as e:
        print(f"[ERROR] 提取数据失败: {str(e)}")
        return {}


def compare_data(test_data, answer_data):
    """对比测试组和答案组的完整数据（一级字段 + 项目数组）"""
    comparison_result = {
        'total_fields': 0,
        'matched_fields': 0,
        'field_stats': {},
        'details': [],
        'field_names': []
    }
    
    # 收集所有一级字段名（排除"项目"数组）
    level1_fields = set()
    for data in [test_data, answer_data]:
        if isinstance(data, dict):
            level1_fields.update([k for k in data.keys() if k != '项目'])
    
    level1_fields = sorted(list(level1_fields))
    
    # 1. 对比一级字段
    for field in level1_fields:
        test_value = test_data.get(field, {}).get('text', '').strip() if isinstance(test_data.get(field), dict) else ''
        answer_value = answer_data.get(field, {}).get('text', '').strip() if isinstance(answer_data.get(field), dict) else ''
        
        is_match = test_value == answer_value
        
        # 初始化字段统计
        if field not in comparison_result['field_stats']:
            comparison_result['field_stats'][field] = {'matched': 0, 'total': 0}
            comparison_result['field_names'].append(field)
        
        comparison_result['total_fields'] += 1
        comparison_result['field_stats'][field]['total'] += 1
        
        if is_match:
            comparison_result['matched_fields'] += 1
            comparison_result['field_stats'][field]['matched'] += 1
        
        comparison_result['details'].append({
            'level': 1,  # 一级字段
            'field_path': field,
            'field_name': field,
            'test_value': test_value,
            'answer_value': answer_value,
            'match': is_match
        })
    
    # 2. 对比"项目"数组（按顺序匹配）
    test_items = test_data.get('项目', [])
    answer_items = answer_data.get('项目', [])
    
    if test_items or answer_items:
        max_items = max(len(test_items), len(answer_items))
        
        # 收集项目内的所有字段名
        item_fields = set()
        for items_list in [test_items, answer_items]:
            for item in items_list:
                if isinstance(item, dict):
                    item_fields.update(item.keys())
        
        item_fields = sorted(list(item_fields))
        
        # 按顺序对比每个项目
        for i in range(max_items):
            test_item = test_items[i] if i < len(test_items) else {}
            answer_item = answer_items[i] if i < len(answer_items) else {}
            
            for field in item_fields:
                test_value = test_item.get(field, {}).get('text', '').strip() if isinstance(test_item.get(field), dict) else ''
                answer_value = answer_item.get(field, {}).get('text', '').strip() if isinstance(answer_item.get(field), dict) else ''
                
                is_match = test_value == answer_value
                
                # 字段路径：项目[1].商品编号
                field_path = f"项目[{i+1}].{field}"
                
                # 初始化字段统计
                if field_path not in comparison_result['field_stats']:
                    comparison_result['field_stats'][field_path] = {'matched': 0, 'total': 0}
                    comparison_result['field_names'].append(field_path)
                
                comparison_result['total_fields'] += 1
                comparison_result['field_stats'][field_path]['total'] += 1
                
                if is_match:
                    comparison_result['matched_fields'] += 1
                    comparison_result['field_stats'][field_path]['matched'] += 1
                
                comparison_result['details'].append({
                    'level': 2,  # 二级字段（项目数组内）
                    'item_index': i + 1,
                    'field_path': field_path,
                    'field_name': field,
                    'test_value': test_value,
                    'answer_value': answer_value,
                    'match': is_match
                })
    
    # 计算准确率
    if comparison_result['total_fields'] > 0:
        comparison_result['accuracy'] = (comparison_result['matched_fields'] / 
                                         comparison_result['total_fields'] * 100)
    else:
        comparison_result['accuracy'] = 0
    
    return comparison_result


def process_test_task(task_id, groups_data):
    """处理测试任务的主函数"""
    try:
        socketio.emit('progress_update', {
            'task_id': task_id,
            'status': 'running',
            'message': '开始处理测试任务...',
            'progress': 0
        })
        
        all_results = []
        total_groups = len(groups_data)
        
        for group_idx, group in enumerate(groups_data):
            group_name = group.get('name', f'大组{group_idx + 1}')
            test_files = group.get('test_files', [])
            answer_files = group.get('answer_files', [])
            
            socketio.emit('progress_update', {
                'task_id': task_id,
                'status': 'running',
                'message': f'正在处理 {group_name}...',
                'progress': int((group_idx / total_groups) * 100)
            })
            
            try:
                # 准备测试组文件路径
                test_file_paths = [os.path.join(app.config['UPLOAD_FOLDER'], f) for f in test_files]
                answer_file_paths = [os.path.join(app.config['UPLOAD_FOLDER'], f) for f in answer_files]
                
                # 提取测试组字段
                socketio.emit('progress_update', {
                    'task_id': task_id,
                    'status': 'running',
                    'message': f'{group_name}: 提取测试组字段（{len(test_files)}个文件）...',
                    'progress': int((group_idx / total_groups) * 100)
                })
                
                test_response = extract_fields_from_files(test_file_paths)
                test_data = extract_data_from_response(test_response)
                
                # 提取答案组字段
                socketio.emit('progress_update', {
                    'task_id': task_id,
                    'status': 'running',
                    'message': f'{group_name}: 提取答案组字段（{len(answer_files)}个文件）...',
                    'progress': int((group_idx / total_groups) * 100)
                })
                
                answer_response = extract_fields_from_files(answer_file_paths)
                answer_data = extract_data_from_response(answer_response)
                
                # 对比结果
                socketio.emit('progress_update', {
                    'task_id': task_id,
                    'status': 'running',
                    'message': f'{group_name}: 对比结果...',
                    'progress': int((group_idx / total_groups) * 100)
                })
                
                comparison = compare_data(test_data, answer_data)
                
                all_results.append({
                    'group_name': group_name,
                    'test_files': test_files,
                    'answer_files': answer_files,
                    'comparison': comparison
                })
                
            except Exception as group_error:
                error_msg = f"{group_name} 处理失败: {str(group_error)}"
                
                socketio.emit('progress_update', {
                    'task_id': task_id,
                    'status': 'running',
                    'message': f'⚠️ {error_msg}，跳过该组继续处理...',
                    'progress': int((group_idx / total_groups) * 100)
                })
                
                # 记录失败的大组
                all_results.append({
                    'group_name': group_name,
                    'test_files': test_files,
                    'answer_files': answer_files,
                    'error': str(group_error),
                    'comparison': {
                        'total_fields': 0,
                        'matched_fields': 0,
                        'accuracy': 0,
                        'field_stats': {},
                        'details': [],
                        'field_names': []
                    }
                })
        
        # 生成报告
        socketio.emit('progress_update', {
            'task_id': task_id,
            'status': 'running',
            'message': '生成测试报告...',
            'progress': 95
        })
        
        html_report = generate_html_report(all_results)
        excel_path = generate_excel_report(task_id, all_results)
        
        task_results[task_id] = {
            'status': 'completed',
            'results': all_results,
            'html_report': html_report,
            'excel_path': excel_path
        }
        
        print(f"[DEBUG] 任务 {task_id} 完成，已保存到 task_results")
        print(f"[DEBUG] Excel文件路径: {excel_path}")
        print(f"[DEBUG] 文件是否存在: {os.path.exists(excel_path)}")
        
        socketio.emit('progress_update', {
            'task_id': task_id,
            'status': 'completed',
            'message': '测试完成！',
            'progress': 100,
            'html_report': html_report
        })
        
        # 清理上传的文件
        cleanup_uploaded_files(groups_data)
        
    except Exception as e:
        error_msg = f'处理失败: {str(e)}'
        
        socketio.emit('progress_update', {
            'task_id': task_id,
            'status': 'error',
            'message': error_msg,
            'progress': 0,
            'detailed_error': traceback.format_exc()
        })
        task_results[task_id] = {
            'status': 'error',
            'error': str(e),
            'detailed_error': traceback.format_exc()
        }
        
        print(f"[DEBUG] 任务 {task_id} 失败，已保存错误信息到 task_results")


def cleanup_uploaded_files(groups_data):
    """清理上传的临时文件"""
    try:
        for group in groups_data:
            for file_list in [group.get('test_files', []), group.get('answer_files', [])]:
                for filename in file_list:
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
                    if os.path.exists(file_path):
                        os.remove(file_path)
    except Exception:
        pass  # 清理失败不影响主流程


def generate_html_report(results):
    """生成HTML格式的测试报告"""
    # 计算总体统计
    total_groups = len(results)
    total_matched = sum(r['comparison']['matched_fields'] for r in results)
    total_fields = sum(r['comparison']['total_fields'] for r in results)
    overall_accuracy = (total_matched / total_fields * 100) if total_fields > 0 else 0
    
    # 动态收集所有字段名
    field_names_set = set()
    for result in results:
        if 'field_names' in result['comparison']:
            field_names_set.update(result['comparison']['field_names'])
        else:
            field_names_set.update(result['comparison']['field_stats'].keys())
    
    field_names = sorted(list(field_names_set))
    
    # 计算字段统计
    field_stats = {field: {'matched': 0, 'total': 0} for field in field_names}
    
    for result in results:
        for field in field_names:
            if field in result['comparison']['field_stats']:
                stats = result['comparison']['field_stats'][field]
                field_stats[field]['matched'] += stats['matched']
                field_stats[field]['total'] += stats['total']
    
    # 生成HTML
    html = f"""
    <div class="report-container">
        <h2>测试报告</h2>
        <div class="alert alert-info">
            <h4>总体概览</h4>
            <p><strong>测试大组数:</strong> {total_groups}</p>
            <p><strong>总字段数:</strong> {total_fields}</p>
            <p><strong>匹配字段数:</strong> {total_matched}</p>
            <p><strong>总体准确率:</strong> {overall_accuracy:.2f}%</p>
        </div>
        
        <h4>各字段准确率统计</h4>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>字段名</th>
                    <th>匹配数</th>
                    <th>总数</th>
                    <th>准确率</th>
                    <th>准确率可视化</th>
                </tr>
            </thead>
            <tbody>
    """
    
    for field in field_names:
        stats = field_stats[field]
        accuracy = (stats['matched'] / stats['total'] * 100) if stats['total'] > 0 else 0
        html += f"""
                <tr>
                    <td>{field}</td>
                    <td>{stats['matched']}</td>
                    <td>{stats['total']}</td>
                    <td>{accuracy:.2f}%</td>
                    <td>
                        <div class="progress">
                            <div class="progress-bar {'bg-success' if accuracy >= 90 else 'bg-warning' if accuracy >= 70 else 'bg-danger'}" 
                                 style="width: {accuracy}%">{accuracy:.1f}%</div>
                        </div>
                    </td>
                </tr>
        """
    
    html += """
            </tbody>
        </table>
        
        <h4>大组详细结果</h4>
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>大组名称</th>
                    <th>测试文件数</th>
                    <th>答案文件数</th>
                    <th>准确率</th>
                    <th>状态</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
    """
    
    for idx, result in enumerate(results):
        status = "❌ 失败" if 'error' in result else "✅ 成功"
        status_class = "table-danger" if 'error' in result else "table-success"
        html += f"""
                <tr class="{status_class}">
                    <td>{result['group_name']}</td>
                    <td>{len(result['test_files'])}</td>
                    <td>{len(result['answer_files'])}</td>
                    <td>{result['comparison']['accuracy']:.2f}%</td>
                    <td>{status}</td>
                    <td><button class="btn btn-sm btn-primary" onclick="showGroupDetail({idx})">查看详情</button></td>
                </tr>
        """
    
    html += """
            </tbody>
        </table>
        
        <h4>详细对比结果</h4>
        <div id="detail-container">
    """
    
    for idx, result in enumerate(results):
        error_info = f"<div class='alert alert-danger'><strong>错误:</strong> {result.get('error', '')}</div>" if 'error' in result else ""
        
        html += f"""
            <div class="group-detail" id="group-detail-{idx}" style="display:none;">
                <h5>{result['group_name']}</h5>
                <p><strong>测试文件:</strong> {', '.join(result['test_files'])}</p>
                <p><strong>答案文件:</strong> {', '.join(result['answer_files'])}</p>
                <p><strong>准确率:</strong> {result['comparison']['accuracy']:.2f}%</p>
                {error_info}
        """
        
        if result['comparison']['details']:
            html += """
                <table class="table table-sm table-bordered">
                    <thead>
                        <tr>
                            <th>层级</th>
                            <th>字段路径</th>
                            <th>测试值</th>
                            <th>答案值</th>
                            <th>状态</th>
                        </tr>
                    </thead>
                    <tbody>
            """
            
            for detail in result['comparison']['details']:
                match_class = 'table-success' if detail['match'] else 'table-danger'
                match_icon = '✓' if detail['match'] else '✗'
                level_text = '一级字段' if detail['level'] == 1 else f"项目[{detail.get('item_index', '')}]"
                html += f"""
                        <tr class="{match_class}">
                            <td>{level_text}</td>
                            <td>{detail['field_path']}</td>
                            <td>{detail['test_value']}</td>
                            <td>{detail['answer_value']}</td>
                            <td>{match_icon}</td>
                        </tr>
                """
            
            html += """
                    </tbody>
                </table>
            """
        
        html += "</div>"
    
    html += """
        </div>
    </div>
    
    <script>
    function showGroupDetail(idx) {
        document.querySelectorAll('.group-detail').forEach(el => {
            el.style.display = 'none';
        });
        document.getElementById('group-detail-' + idx).style.display = 'block';
        document.getElementById('detail-container').scrollIntoView({behavior: 'smooth'});
    }
    </script>
    """
    
    return html


def generate_excel_report(task_id, results):
    """生成Excel格式的测试报告"""
    wb = Workbook()
    
    # Sheet1: 总体统计
    ws1 = wb.active
    ws1.title = "总体统计"
    
    total_groups = len(results)
    total_matched = sum(r['comparison']['matched_fields'] for r in results)
    total_fields = sum(r['comparison']['total_fields'] for r in results)
    overall_accuracy = (total_matched / total_fields * 100) if total_fields > 0 else 0
    
    ws1['A1'] = '指标'
    ws1['B1'] = '数值'
    ws1['A2'] = '测试大组数'
    ws1['B2'] = total_groups
    ws1['A3'] = '总字段数'
    ws1['B3'] = total_fields
    ws1['A4'] = '匹配字段数'
    ws1['B4'] = total_matched
    ws1['A5'] = '总体准确率'
    ws1['B5'] = f"{overall_accuracy:.2f}%"
    
    # 设置表头样式
    header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
    header_font = Font(color="FFFFFF", bold=True)
    for cell in ws1[1]:
        cell.fill = header_fill
        cell.font = header_font
    
    # Sheet2: 大组汇总
    ws2 = wb.create_sheet("大组汇总")
    ws2.append(['大组名称', '测试文件数', '答案文件数', '总字段数', '匹配字段数', '准确率', '状态'])
    
    for result in results:
        status = "失败" if 'error' in result else "成功"
        ws2.append([
            result['group_name'],
            len(result['test_files']),
            len(result['answer_files']),
            result['comparison']['total_fields'],
            result['comparison']['matched_fields'],
            f"{result['comparison']['accuracy']:.2f}%",
            status
        ])
    
    for cell in ws2[1]:
        cell.fill = header_fill
        cell.font = header_font
    
    # Sheet3: 字段汇总
    ws3 = wb.create_sheet("字段汇总")
    ws3.append(['字段名', '匹配数', '总数', '准确率'])
    
    # 动态收集所有字段名
    field_names_set = set()
    for result in results:
        if 'field_names' in result['comparison']:
            field_names_set.update(result['comparison']['field_names'])
        else:
            field_names_set.update(result['comparison']['field_stats'].keys())
    
    field_names = sorted(list(field_names_set))
    field_stats = {field: {'matched': 0, 'total': 0} for field in field_names}
    
    for result in results:
        for field in field_names:
            if field in result['comparison']['field_stats']:
                stats = result['comparison']['field_stats'][field]
                field_stats[field]['matched'] += stats['matched']
                field_stats[field]['total'] += stats['total']
    
    for field in field_names:
        stats = field_stats[field]
        accuracy = (stats['matched'] / stats['total'] * 100) if stats['total'] > 0 else 0
        ws3.append([field, stats['matched'], stats['total'], f"{accuracy:.2f}%"])
    
    for cell in ws3[1]:
        cell.fill = header_fill
        cell.font = header_font
    
    # Sheet4: 详细对比数据
    ws4 = wb.create_sheet("详细对比数据")
    ws4.append(['大组名称', '层级', '字段路径', '测试值', '答案值', '是否匹配'])
    
    for result in results:
        for detail in result['comparison']['details']:
            level_text = '一级字段' if detail['level'] == 1 else f"项目[{detail.get('item_index', '')}]"
            ws4.append([
                result['group_name'],
                level_text,
                detail['field_path'],
                detail['test_value'],
                detail['answer_value'],
                '匹配' if detail['match'] else '不匹配'
            ])
    
    for cell in ws4[1]:
        cell.fill = header_fill
        cell.font = header_font
    
    # 应用条件格式
    red_fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
    green_fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
    
    for row in range(2, ws4.max_row + 1):
        match_status = ws4[f'F{row}'].value
        fill = green_fill if match_status == '匹配' else red_fill
        for col in range(1, 7):
            ws4.cell(row, col).fill = fill
    
    # 保存Excel文件
    excel_filename = f"report_{task_id}.xlsx"
    excel_path = os.path.join(app.config['REPORT_FOLDER'], excel_filename)
    wb.save(excel_path)
    
    return excel_path


@app.route('/')
def index():
    """主页"""
    return render_template('index.html')


@app.route('/api/upload_files', methods=['POST'])
def upload_files():
    """上传文件接口"""
    try:
        files = request.files.getlist('files')
        saved_files = []
        
        for file in files:
            if file and file.filename:
                original_filename = file.filename
                
                # 获取文件扩展名
                _, ext = os.path.splitext(original_filename)
                ext = ext.lower()
                
                # 使用secure_filename处理文件名，可能会丢失扩展名
                safe_filename = secure_filename(original_filename)
                
                # 如果secure_filename处理后丢失了扩展名，重新添加
                if not safe_filename.endswith(ext) and ext:
                    base_name = os.path.splitext(safe_filename)[0]
                    safe_filename = base_name + ext
                
                # 如果还是没有扩展名，尝试从MIME类型推断
                if not ext:
                    content_type = file.content_type
                    if content_type == 'application/pdf':
                        ext = '.pdf'
                        safe_filename += ext
                
                # 添加时间戳避免文件名冲突
                timestamp = datetime.now().strftime('%Y%m%d%H%M%S%f')
                final_filename = f"{timestamp}_{safe_filename}"
                
                filepath = os.path.join(app.config['UPLOAD_FOLDER'], final_filename)
                file.save(filepath)
                saved_files.append(final_filename)
        
        return jsonify({
            'success': True,
            'files': saved_files
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@app.route('/api/start_test', methods=['POST'])
def start_test():
    """启动测试任务"""
    try:
        groups_data = request.json.get('groups', [])
        
        if not groups_data:
            return jsonify({
                'success': False,
                'error': '没有提供测试组数据'
            }), 400
        
        task_id = str(uuid.uuid4())
        
        # 在后台线程中处理任务
        thread = threading.Thread(
            target=process_test_task,
            args=(task_id, groups_data)
        )
        thread.daemon = True
        thread.start()
        
        return jsonify({
            'success': True,
            'task_id': task_id
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@app.route('/api/task_status/<task_id>')
def get_task_status(task_id):
    """获取任务状态"""
    try:
        if task_id not in task_results:
            return jsonify({
                'success': False,
                'error': '任务不存在',
                'available_tasks': list(task_results.keys())
            }), 404
        
        task_result = task_results[task_id]
        return jsonify({
            'success': True,
            'task_id': task_id,
            'status': task_result['status'],
            'has_excel': 'excel_path' in task_result and os.path.exists(task_result.get('excel_path', ''))
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


@app.route('/api/download_report/<task_id>')
def download_report(task_id):
    """下载Excel报告"""
    try:
        print(f"[DEBUG] 请求下载报告，任务ID: {task_id}")
        print(f"[DEBUG] 当前存储的任务IDs: {list(task_results.keys())}")
        
        if task_id not in task_results:
            print(f"[ERROR] 任务ID {task_id} 不存在于 task_results 中")
            return jsonify({
                'success': False,
                'error': f'任务不存在，当前任务ID: {task_id}'
            }), 404
        
        task_result = task_results[task_id]
        
        if task_result['status'] != 'completed':
            return jsonify({
                'success': False,
                'error': '任务未完成'
            }), 400
        
        excel_path = task_result['excel_path']
        
        if not os.path.exists(excel_path):
            return jsonify({
                'success': False,
                'error': '报告文件不存在'
            }), 404
        
        return send_file(
            excel_path,
            as_attachment=True,
            download_name=f'测试报告_{datetime.now().strftime("%Y%m%d_%H%M%S")}.xlsx'
        )
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500


if __name__ == '__main__':
    socketio.run(app, debug=True, host='0.0.0.0', port=5000)